package com.yipai.datewidget.booking;

import static org.jaaksi.pickerview.picker.TimePicker.DEFAULT_TIME_FORMAT;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;

import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.lxj.xpopup.util.XPopupUtils;
import com.yipai.datewidget.booking.base.BaseBottomPopupView;
import com.yipai.datewidget.booking.base.BaseFragment;
import com.yipai.datewidget.booking.base.EventDispatcher;
import com.yipai.datewidget.booking.model.BookingInfoModel;
import com.yipai.datewidget.booking.page.CalendarFragment;
import com.yipai.datewidget.booking.page.RemarksFragment;
import com.yipai.datewidget.booking.page.TimePickerFragment;
import com.yipai.datewidget.booking.databinding.PopupLayoutBookingBinding;
import com.yipai.datewidget.booking.databinding.ViewMenuTabBinding;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class BookingPopupWindow extends BaseBottomPopupView {

    public static final int INDEX_FIRST = 0;
    public static final int INDEX_SECOND = 1;
    public static final int INDEX_THIRD = 2;

    public BookingPopupWindow(@NonNull Context context) {
        super(context);
    }

    @Override
    protected int getImplLayoutId() {
        return R.layout.popup_layout_booking;
    }

    public static final int[] sMenuTextId = {R.string.booking_date, R.string.booking_time, R.string.remarks};

    private FragmentActivity mActivity;
    private PopupLayoutBookingBinding mPopupLayoutBookingBinding;
    private BaseFragment[] mPageList;
    private BookingSharedViewModel mBookingSharedViewModel;
    private BookingInfoSubmitListener mBookingInfoSubmitListener;
    private BookingInfoModel mBookingInfoModel;

    public BookingPopupWindow setBookingInfoModel(BookingInfoModel bookingInfoModel) {
        mBookingInfoModel = bookingInfoModel;
        return this;
    }

    @Override
    protected void onCreate() {
        super.onCreate();
        mPopupLayoutBookingBinding = DataBindingUtil.bind(getPopupImplView());
        mActivity = (FragmentActivity) getContext();
        mBookingSharedViewModel = getActivityScopeViewModel(BookingSharedViewModel.class);

        initData();
        initTab();
        initObserver();
    }

    private void initObserver() {
        mBookingSharedViewModel.mNextStepUnPeekLiveData.observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer index) {
                if(index == mPageList.length - 1){
                    // 点击完成 开始校验
                    // 校验提交的日期
                    Date dayDate = mBookingSharedViewModel.mDayDateMutableLiveData.getValue();
                    if(dayDate == null){
                        // unknown error
                        return;
                    }

                    // 校验提交的时间
                    Date startTimeDate = mBookingSharedViewModel.mStartTimeMutableLiveData.getValue();
                    Date endTimeDate = mBookingSharedViewModel.mEndTimeMutableLiveData.getValue();

                    if(startTimeDate == null || endTimeDate == null){
                        // unknown error
                        return;
                    }
                    String startTime = DEFAULT_TIME_FORMAT.format(startTimeDate);
                    String endTime = DEFAULT_TIME_FORMAT.format(endTimeDate);
                    if (endTime.compareTo(startTime) <= 0) {
                        Toast.makeText(getContext(), R.string.time_picker_range_error_tips, Toast.LENGTH_SHORT).show();
                        return;
                    }

                    String remarks = mBookingSharedViewModel.mRemarksMutableLiveData.getValue();


                    if(mBookingInfoSubmitListener != null){
                        BookingInfoModel bookingInfoModel = new BookingInfoModel();
                        bookingInfoModel.setDayDate(dayDate);
                        bookingInfoModel.setStartTimeDate(startTimeDate);
                        bookingInfoModel.setEndTimeDate(endTimeDate);
                        bookingInfoModel.setRemarks(remarks);
                        mBookingInfoSubmitListener.onSubmit(bookingInfoModel);
                    }
                    dismiss();
                } else {
                    // 下一步
                    mPopupLayoutBookingBinding.vpContainer.setCurrentItem(index + 1);
                }
            }
        });
    }

    private void initData() {
        mPageList = new BaseFragment[]{
                CalendarFragment.newInstance(INDEX_FIRST),
                TimePickerFragment.newInstance(INDEX_SECOND),
                RemarksFragment.newInstance(INDEX_THIRD)
        };

        if(mBookingInfoModel != null){
            mBookingSharedViewModel.mStartTimeMutableLiveData.setValue(mBookingInfoModel.getStartTimeDate());
            mBookingSharedViewModel.mEndTimeMutableLiveData.setValue(mBookingInfoModel.getEndTimeDate());
            mBookingSharedViewModel.mDayDateMutableLiveData.setValue(mBookingInfoModel.getDayDate());
            mBookingSharedViewModel.mRemarksMutableLiveData.setValue(mBookingInfoModel.getRemarks());
        }
    }

    private void initTab() {
        mPopupLayoutBookingBinding.vpContainer.setOffscreenPageLimit(mPageList.length);
        mPopupLayoutBookingBinding.vpContainer.setUserInputEnabled(false);
        mPopupLayoutBookingBinding.vpContainer.setAdapter(new FragmentStateAdapter(mActivity.getSupportFragmentManager(), getLifecycle()) {
            @NonNull
            @Override
            public Fragment createFragment(int position) {
                //FragmentStateAdapter内部自己会管理已实例化的fragment对象。
                // 所以不需要考虑复用的问题
                return mPageList[position];
            }

            @Override
            public int getItemCount() {
                return mPageList.length;
            }
        });
        mPopupLayoutBookingBinding.vpContainer.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);

                for (EventDispatcher eventDispatcher : mPageList) {
                    eventDispatcher.onEvent();
                }
            }
        });

        TabLayoutMediator mediator = new TabLayoutMediator(mPopupLayoutBookingBinding.tlMenu, mPopupLayoutBookingBinding.vpContainer, new TabLayoutMediator.TabConfigurationStrategy() {
            @Override
            public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
                ViewMenuTabBinding viewMenuTabBinding = DataBindingUtil.inflate(LayoutInflater.from(mActivity), R.layout.view_menu_tab, null, false);

                String tabText = getResources().getString(sMenuTextId[position]);
                viewMenuTabBinding.tvTitle.setText(tabText);
                tab.setCustomView(viewMenuTabBinding.getRoot());
            }
        });

        mPopupLayoutBookingBinding.tlMenu.setSelectedTabIndicator(null);
        mPopupLayoutBookingBinding.tlMenu.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                onTabChangedView(tab, true);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                onTabChangedView(tab, false);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

        mediator.attach();
        mPopupLayoutBookingBinding.tlMenu.setTabMode(TabLayout.MODE_FIXED);
        mPopupLayoutBookingBinding.tlMenu.setTabGravity(TabLayout.GRAVITY_FILL);

    }

    private void onTabChangedView(TabLayout.Tab tab, boolean isSelected) {
        View customView = tab.getCustomView();
        if(customView == null){
            return;
        }
        ViewMenuTabBinding viewMenuTabBinding = DataBindingUtil.bind(tab.getCustomView());
        if(viewMenuTabBinding != null){
            viewMenuTabBinding.tvTitle.setSelected(isSelected);
            viewMenuTabBinding.itemVIndicator.setVisibility(isSelected ? VISIBLE : INVISIBLE);
        }
    }

    @Override
    protected List<String> getInternalFragmentNames() {
        if(mPageList != null) {
            List<String> names = new ArrayList<>();
            for (Fragment page : mPageList) {
                names.add(page.getClass().getSimpleName());
            }
            return names;
        }
        return null;
    }

    @Override
    protected int getMaxHeight() {
        return (int) (XPopupUtils.getScreenHeight(getContext())*.65f);
    }

    @Override
    public void destroy() {
        super.destroy();

        // 清空数据
        mBookingSharedViewModel.mRemarksMutableLiveData.setValue(null);
        mBookingSharedViewModel.mEndTimeMutableLiveData.setValue(null);
        mBookingSharedViewModel.mStartTimeMutableLiveData.setValue(null);
        mBookingSharedViewModel.mDayDateMutableLiveData.setValue(null);
    }

    public BookingPopupWindow setBookingInfoSubmitListener(BookingInfoSubmitListener bookingInfoSubmitListener) {
        mBookingInfoSubmitListener = bookingInfoSubmitListener;
        return this;
    }

    public interface BookingInfoSubmitListener{
        void onSubmit(BookingInfoModel bookingInfoModel);
    }

}
